`include "define.v"
// ParaCPU register file: 2W2R, 1T write, 0T read
module regFile (
   input clk,
   input rst_n,
   input [3:0] d_srcA,
   input [3:0] d_srcB,
   output [31:0] d_rvalA,
   output [31:0] d_rvalB,
   input [3:0] w_dstE, 
   input [3:0] w_dstM,
   input [1:0]w_wordselE,//00-rx,01-rxL,1x-rxH
   input [1:0]w_wordselM,//00-rx,01-rxL,1x-rxH
   input [31:0] w_valE,
   input [31:0] w_valM
   );
   
reg [31:0] r0,r1,r2,r3,r4,r5,r6,r7;
// read logic
assign d_rvalA = 
              (d_srcA == 4'h0) ? r0 :
              (d_srcA == 4'h1) ? r1 :
              (d_srcA == 4'h2) ? r2 :
              (d_srcA == 4'h3) ? r3 :
              (d_srcA == 4'h4) ? r4 :
              (d_srcA == 4'h5) ? r5 :
              (d_srcA == 4'h6) ? r6 :
              (d_srcA == 4'h7) ? r7 :
              32'h0;

assign d_rvalB = 
              (d_srcB == 4'h0) ? r0 :
              (d_srcB == 4'h1) ? r1 :
              (d_srcB == 4'h2) ? r2 :
              (d_srcB == 4'h3) ? r3 :
              (d_srcB == 4'h4) ? r4 :
              (d_srcB == 4'h5) ? r5 :
              (d_srcB == 4'h6) ? r6 :
              (d_srcB == 4'h7) ? r7 :
              32'h0;

// write logic
always @(posedge clk or negedge rst_n) 
begin
    if(~rst_n)
        begin
            r0 <= 32'h0000_0000;
        end 
    else 
        begin
        if(w_dstM == 4'h0) 
        begin
            r0[15:0]<=(w_wordselM==2'b00 |w_wordselM==2'b01)  ? w_valM[15:0] :r0[15:0];
            r0[31:16]<=(w_wordselM==2'b00 | w_wordselM==2'b10 |w_wordselM==2'b11)  ? w_valM[31:16] :r0[31:16];
        end
        else if(w_dstE == 4'h0) 
        begin
            r0[15:0]<=(w_wordselE==2'b00 |w_wordselE==2'b01)  ? w_valE[15:0] :r0[15:0];
            r0[31:16]<=(w_wordselE==2'b00 | w_wordselE==2'b10 |w_wordselE==2'b11)  ? w_valE[31:16] :r0[31:16];
        end
        end
end

always @(posedge clk or negedge rst_n) 
begin
    if(~rst_n)
        begin
            r1 <= 32'h0000_0000;
        end 
    else 
        begin
        if(w_dstM == 4'h1) 
        begin
            r1[15:0]<=(w_wordselM==2'b00 |w_wordselM==2'b01)  ? w_valM[15:0] :r1[15:0];
            r1[31:16]<=(w_wordselM==2'b00 | w_wordselM==2'b10 |w_wordselM==2'b11)  ? w_valM[31:16] :r1[31:16];
        end
        else if(w_dstE == 4'h1) 
        begin
            r1[15:0]<=(w_wordselE==2'b00 |w_wordselE==2'b01)  ? w_valE[15:0] :r1[15:0];
            r1[31:16]<=(w_wordselE==2'b00 | w_wordselE==2'b10 |w_wordselE==2'b11)  ? w_valE[31:16] :r1[31:16];
        end
        end
end
always @(posedge clk or negedge rst_n)
begin
    if(~rst_n)
        begin
            r2 <= 32'h0000_0000;
        end 
    else 
        begin
        if(w_dstM == 4'h2) 
        begin
            r2[15:0]<=(w_wordselM==2'b00 |w_wordselM==2'b01)  ? w_valM[15:0] :r2[15:0];
            r2[31:16]<=(w_wordselM==2'b00 | w_wordselM==2'b10 |w_wordselM==2'b11)  ? w_valM[31:16] :r2[31:16];
        end
        else if(w_dstE == 4'h2) 
        begin
            r2[15:0]<=(w_wordselE==2'b00 |w_wordselE==2'b01)  ? w_valE[15:0] :r2[15:0];
            r2[31:16]<=(w_wordselE==2'b00 | w_wordselE==2'b10 |w_wordselE==2'b11)  ? w_valE[31:16] :r2[31:16];
        end
        end
end
always @(posedge clk or negedge rst_n) 
begin
    if(~rst_n)
        begin
            r3 <= 32'h0000_0000;
        end 
    else 
        begin
        if(w_dstM == 4'h3) 
        begin
            r3[15:0]<=(w_wordselM==2'b00 |w_wordselM==2'b01)  ? w_valM[15:0] :r3[15:0];
            r3[31:16]<=(w_wordselM==2'b00 | w_wordselM==2'b10 |w_wordselM==2'b11)  ? w_valM[31:16] :r3[31:16];
        end
        else if(w_dstE == 4'h3) 
        begin
            r3[15:0]<=(w_wordselE==2'b00 |w_wordselE==2'b01)  ? w_valE[15:0] :r3[15:0];
            r3[31:16]<=(w_wordselE==2'b00 | w_wordselE==2'b10 |w_wordselE==2'b11)  ? w_valE[31:16] :r3[31:16];
        end
        end
end
always @(posedge clk or negedge rst_n) 
begin
    if(~rst_n)
        begin
            r4 <= 32'h0000_0000;
        end 
    else
        begin
        if(w_dstM == 4'h4) 
        begin
            r4[15:0]<=(w_wordselM==2'b00 |w_wordselM==2'b01)  ? w_valM[15:0] :r4[15:0];
            r4[31:16]<=(w_wordselM==2'b00 | w_wordselM==2'b10 |w_wordselM==2'b11)  ? w_valM[31:16] :r4[31:16];
        end
        else if(w_dstE == 4'h4) 
        begin
            r4[15:0]<=(w_wordselE==2'b00 |w_wordselE==2'b01)  ? w_valE[15:0] :r4[15:0];
            r4[31:16]<=(w_wordselE==2'b00 | w_wordselE==2'b10 |w_wordselE==2'b11)  ? w_valE[31:16] :r4[31:16];
        end
        end
end

always @(posedge clk or negedge rst_n) 
begin
    if(~rst_n)
    begin
        r5 <= 32'h0000_0000;
    end 
    else 
    begin
        if(w_dstM == 4'h5) 
        begin
            r5[15:0]<=(w_wordselM==2'b00 |w_wordselM==2'b01)  ? w_valM[15:0] :r5[15:0];
            r5[31:16]<=(w_wordselM==2'b00 | w_wordselM==2'b10 |w_wordselM==2'b11)  ? w_valM[31:16] :r5[31:16];
        end
        else if(w_dstE == 4'h5) 
        begin
            r5[15:0]<=(w_wordselE==2'b00 |w_wordselE==2'b01)  ? w_valE[15:0] :r5[15:0];
            r5[31:16]<=(w_wordselE==2'b00 | w_wordselE==2'b10 |w_wordselE==2'b11)  ? w_valE[31:16] :r5[31:16];
        end
    end
end
always @(posedge clk or negedge rst_n) 
begin
    if(~rst_n)
    begin
        r6 <= 32'h0000_0000;
    end 
    else 
    begin
        if(w_dstM == 4'h6) 
        begin
            r6[15:0]<=(w_wordselM==2'b00 |w_wordselM==2'b01)  ? w_valM[15:0] :r6[15:0];
            r6[31:16]<=(w_wordselM==2'b00 | w_wordselM==2'b10 |w_wordselM==2'b11)  ? w_valM[31:16] :r6[31:16];
        end
        else if(w_dstE == 4'h6) 
        begin
            r6[15:0]<=(w_wordselE==2'b00 |w_wordselE==2'b01)  ? w_valE[15:0] :r6[15:0];
            r6[31:16]<=(w_wordselE==2'b00 | w_wordselE==2'b10 |w_wordselE==2'b11)  ? w_valE[31:16] :r6[31:16];
        end
    end
end
always @(posedge clk or negedge rst_n) 
begin
    if(~rst_n)
    begin
        r7 <= 32'h0000_0000;
    end 
    else 
    begin
        if(w_dstM == 4'h7) 
        begin
            r7[15:0]<=(w_wordselM==2'b00 |w_wordselM==2'b01)  ? w_valM[15:0] :r7[15:0];
            r7[31:16]<=(w_wordselM==2'b00 | w_wordselM==2'b10 |w_wordselM==2'b11)  ? w_valM[31:16] :r7[31:16];
        end
        else if(w_dstE == 4'h7) 
        begin
            r7[15:0]<=(w_wordselE==2'b00 |w_wordselE==2'b01)  ? w_valE[15:0] :r7[15:0];
            r7[31:16]<=(w_wordselE==2'b00 | w_wordselE==2'b10 |w_wordselE==2'b11)  ? w_valE[31:16] :r7[31:16];
        end
    end
end
endmodule 